﻿using System;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using GraphDrawing2.V2.Concrete.Model;

namespace GraphDrawing2.Canvas
{
    public partial class CanvasView : UserControl, ICanvasView, IViewPortObserver
    {
        public CanvasController Controller { get; private set; }

        public CanvasView()
        {
            Controller = new CanvasController();
            InitializeComponent();
            SetStyle(ControlStyles.ResizeRedraw | ControlStyles.Selectable | ControlStyles.UserPaint | ControlStyles.DoubleBuffer |
                     ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            Controller.Model.ViewPort.SetObserver(this);
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            using (var transform = Controller.Model.ViewPort.CreateTransformation())
            {
                e.Graphics.Transform = transform;
                Controller.OnDrawBackground(new DrawingContext(e.Graphics, e.ClipRectangle));
                e.Graphics.ResetTransform();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            using (var transform = Controller.Model.ViewPort.CreateTransformation())
            {
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                e.Graphics.CompositingQuality = CompositingQuality.GammaCorrected;
                e.Graphics.Transform = transform;
                Controller.OnDraw(new DrawingContext(e.Graphics, e.ClipRectangle));
                e.Graphics.ResetTransform();
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            Controller.OnMouseDown(e.Location, e.Button, ModifierKeys);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            Controller.OnMouseMove(e.Location, e.Button, ModifierKeys);
        }

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            Controller.OnMouseWheel(e.Delta);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            Controller.OnMouseUp(e.Location, e.Button, ModifierKeys);
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            Controller.Resize(ClientSize);
        }

        public void UpdateView()
        {
            Invalidate();
        }

        void IViewPortObserver.SizeChanged()
        {
            UpdateView();
        }

        void IViewPortObserver.PositionChanged()
        {
            UpdateView();
        }

        void IViewPortObserver.ScaleChanged()
        {
            UpdateView();
        }
    }
}
